home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / extract_slice.pro < prev    next >
Text File  |  1997-07-08  |  8KB  |  222 lines

  1. ; $Id: extract_slice.pro,v 1.6 1997/01/15 03:11:50 ali Exp $
  2. ;
  3. ; Copyright (c) 1992-1997, Research Systems, Inc. All rights reserved.
  4. ;    Unauthorized reproduction prohibited.
  5. ;
  6. ;+
  7. ; NAME:
  8. ;    EXTRACT_SLICE
  9. ;
  10. ; PURPOSE:
  11. ;    This function returns a 2-D planar slice extracted from
  12. ;       3-D volumetric data. The slicing plane may be oriented at
  13. ;       any angle, and may pass through any desired location in the
  14. ;       volume.
  15. ;
  16. ; CATEGORY:
  17. ;    Volume Rendering.
  18. ;
  19. ; CALLING SEQUENCE:
  20. ;       Slice = EXTRACT_SLICE(Vol, X_size, Y_size, X_center, Y_center, $
  21. ;                             Z_center, X_rot, Y_rot, Z_rot)
  22. ;
  23. ; INPUTS:
  24. ;       Vol:        The three dimensional volume of data to slice.
  25. ;                   Data type : Any 3-D array except string or structure.
  26. ;       X_size:     The size of the returned slice in X (The returned
  27. ;                   slice will have the dimensions X_size by Y_size).
  28. ;                   Data type : Long.
  29. ;       Y_size:     The size of the returned slice in Y. To preserve
  30. ;                   the correct aspect ratio of the data, Y_size should
  31. ;                   equal X_size. For optimal results, set X_size and
  32. ;                   Y_size to be greater than or equal to the largest of
  33. ;                   the three dimensions of Vol.
  34. ;                   Data type : Long.
  35. ;       X_center:   The X coordinate (index) within the volume that the
  36. ;                   slicing plane passes through. The center of the
  37. ;                   slicing plane passes through Vol at the coordinate
  38. ;                   (X_center, Y_Center, Z_center).
  39. ;                   Data type : Any scalar numeric value (usually Long).
  40. ;       Y_center:   The Y coordinate (index) within the volume that the
  41. ;                   slicing plane passes through.
  42. ;                   Data type : Any scalar numeric value (usually Long).
  43. ;       Z_center:   The Z coordinate (index) within the volume that the
  44. ;                   slicing plane passes through.
  45. ;                   Data type : Any scalar numeric value (usually Long).
  46. ;       X_rot:      The orientation (X rotation) of the slicing plane.
  47. ;                   Before transformation, the slicing plane is parallel
  48. ;                   to the X-Y plane. The slicing plane transformations
  49. ;                   are performed in the following order :
  50. ;                      1. Rotate Z_rot degrees about the Z axis.
  51. ;                      2. Rotate Y_rot degrees about the Y axis.
  52. ;                      3. Rotate X_rot degrees about the X axis.
  53. ;                      4. Translate the center of the plane to
  54. ;                         X_center, Y_center, Z_center.
  55. ;                   Data type : Float.
  56. ;       Y_rot:      The orientation (Y rotation) of the slicing plane.
  57. ;                   Data type : Float.
  58. ;       Z_rot:      The orientation (Z rotation) of the slicing plane.
  59. ;                   Data type : Float.
  60. ;    
  61. ; KEYWORD PARAMETERS:
  62. ;       CUBIC:      If CUBIC is set, then cubic interpolation is used.
  63. ;                   The default is to use tri-linear interpolation.
  64. ;                   If the SAMPLE keyword is set, then the CUBIC keyword
  65. ;                   is ignored.
  66. ;       OUT_VAL:    If OUT_VAL is set, then the portions of the returned
  67. ;                   slice that lie outside the original volume are set to
  68. ;                   the value passed to OUT_VAL.
  69. ;                   Data type : Any scalar numeric value (usually the same
  70. ;                               type as Vol).
  71. ;       RADIANS:    Set this keyword to a non-zero value to indicate that
  72. ;                   X_rot, Y_rot, and Z_rot are in radians. The default
  73. ;                   is degrees.
  74. ;                   Data type : Int.
  75. ;       SAMPLE:     If SAMPLE is set to a non-zero value then nearest
  76. ;                   neighbor sampling is used to compute the slice.
  77. ;                   Otherwise, tri-linear (or cubic) interpolation is used.
  78. ;                   A small reduction in execution time will result if
  79. ;                   SAMPLE mode is set and the OUT_VAL keyword is NOT
  80. ;                   used.
  81. ;
  82. ; OUTPUTS:
  83. ;       This function returns the planar slice as a two dimensional
  84. ;       array with the same data type as Vol. The dimensions of the
  85. ;       returned array are X_size by Y_size.
  86. ;
  87. ; EXAMPLE:
  88. ;       Display an oblique slice through volumetric data.
  89. ;
  90. ;       ; Create some data.
  91. ;          vol = RANDOMU(s, 40, 40, 40)
  92. ;          FOR i=0, 10 DO vol = SMOOTH(vol, 3)
  93. ;          vol = BYTSCL(vol(3:37, 3:37, 3:37))
  94. ;
  95. ;       ; Extract and display a slice.
  96. ;          slice = EXTRACT_SLICE(vol, 40, 40, 17, 17, 17, 30.0, 30.0, 0.0, $
  97. ;                                OUT_VAL=0B)
  98. ;          TVSCL, REBIN(slice, 400, 400)
  99. ;
  100. ; MODIFICATION HISTORY:
  101. ;       Written by:     Daniel Carr. Wed Sep  2 14:47:07 MDT 1992
  102. ;       Modified by:    Daniel Carr. Mon Nov 21 14:59:45 MST 1994
  103. ;          Improved speed and added the CUBIC keyword.
  104. ;-
  105.  
  106. FUNCTION Extract_Slice, vol, x_size, y_size, $
  107.                         x_center, y_center, z_center, $
  108.                         x_rot, y_rot, z_rot, Radians=radians, $
  109.                         Out_Val=out_val, Sample=p_sample, $
  110.                         Cubic=cubic
  111.  
  112. ; *** Test inputs
  113.  
  114. sz_vol = Size(vol)
  115. IF (sz_vol[0] NE 3L) THEN BEGIN
  116.    Print, 'Volume array must have three dimensions'
  117.    STOP
  118. ENDIF
  119. vol_type = sz_vol[sz_vol[0]+1]
  120. IF (vol_type EQ 0L) THEN BEGIN
  121.    Print, 'Volume array must be defined'
  122.    STOP
  123. ENDIF
  124. IF (vol_type EQ 7L) THEN BEGIN
  125.    Print, 'Invalid volume array type (string)'
  126.    STOP
  127. ENDIF
  128. IF (vol_type EQ 8L) THEN BEGIN
  129.    Print, 'Invalid volume array type (structure)'
  130.    STOP
  131. ENDIF
  132.  
  133. x_size = Long(x_size[0])
  134. IF (x_size LT 2L) THEN BEGIN
  135.    Print, 'X_size must be >= 2'
  136.    STOP
  137. ENDIF
  138. y_size = Long(y_size[0])
  139. IF (y_size LT 2L) THEN BEGIN
  140.    Print, 'Y_size must be >= 2'
  141.    STOP
  142. ENDIF
  143.  
  144. x_center = Float(x_center[0])
  145. IF ((x_center LT 0.0) OR (x_center GE Float(sz_vol[1]))) THEN BEGIN
  146.    Print, 'X_center must be >= 0 and less than the x dimension of vol'
  147.    STOP
  148. ENDIF
  149. y_center = Float(y_center[0])
  150. IF ((y_center LT 0.0) OR (y_center GE Float(sz_vol[2]))) THEN BEGIN
  151.    Print, 'Y_center must be >= 0 and less than the y dimension of vol'
  152.    STOP
  153. ENDIF
  154. z_center = Float(z_center[0])
  155. IF ((z_center LT 0.0) OR (z_center GE Float(sz_vol[3]))) THEN BEGIN
  156.    Print, 'Z_center must be >= 0 and less than the z dimension of vol'
  157.    STOP
  158. ENDIF
  159.  
  160. x_rot = Float(x_rot[0])
  161. y_rot = Float(y_rot[0])
  162. z_rot = Float(z_rot[0])
  163.  
  164. IF (N_Elements(radians) GT 0L) THEN BEGIN
  165.    IF (radians[0] NE 0) THEN BEGIN
  166.       x_rot = x_rot * !RADEG
  167.       y_rot = y_rot * !RADEG
  168.       z_rot = z_rot * !RADEG
  169.    ENDIF
  170. ENDIF
  171.  
  172. ; *** Set up the required variables
  173.  
  174. IF (N_Elements(out_val) GT 0L) THEN set_out = 1B ELSE set_out = 0B
  175.  
  176. sample = 0B
  177. IF (N_Elements(p_sample) GT 0L) THEN sample = Byte(p_sample[0])
  178.  
  179. vol_ind = [[Reform((Findgen(x_size) # Replicate(1.0, y_size)), (x_size * y_size))], $
  180.            [Reform((Replicate(1.0, x_size) # Findgen(y_size)), (x_size * y_size))], $
  181.            [Replicate(0.0, (x_size * y_size))], [Replicate(1.0, (x_size * y_size))]]
  182.  
  183. ; *** Extract the slice
  184.  
  185. save_pt = !P.T
  186. T3d, /Reset
  187. T3d, Translate=[-(Float(x_size-1L)/2.0), -(Float(y_size-1L)/2.0), 0.0]
  188. T3d, Rotate=[0.0, 0.0, z_rot]
  189. T3d, Rotate=[0.0, y_rot, 0.0]
  190. T3d, Rotate=[x_rot, 0.0, 0.0]
  191. T3d, Translate=Float([x_center, y_center, z_center])
  192. vol_ind = vol_ind # !P.T
  193. !P.T = save_pt
  194.  
  195. IF (sample) THEN BEGIN
  196.    slice = Reform((vol[0>vol_ind[*, 0]<(sz_vol[1]-1), $
  197.                   0>vol_ind[*, 1]<(sz_vol[2]-1), $
  198.                   0>vol_ind[*, 2]<(sz_vol[3]-1)]), x_size, y_size)
  199.    IF (set_out) THEN BEGIN
  200.       out_v = Where((((vol_ind[*, 0] LT 0.0) OR $
  201.                       (vol_ind[*, 0] GE sz_vol[1])) OR $
  202.                      ((vol_ind[*, 1] LT 0.0) OR $
  203.                       (vol_ind[*, 1] GE sz_vol[2]))) OR $
  204.                      ((vol_ind[*, 2] LT 0.0) OR (vol_ind[*, 2] GE sz_vol[3])))
  205.       IF (out_v[0] GE 0L) THEN slice[out_v] = out_val
  206.    ENDIF
  207. ENDIF ELSE BEGIN
  208.    IF (set_out) THEN BEGIN
  209.       slice = $
  210.          Reform((Interpolate(vol, $
  211.             vol_ind[*, 0], vol_ind[*, 1], vol_ind[*, 2], $
  212.             Missing=out_val, Cubic=Keyword_Set(cubic))), x_size, y_size)
  213.    ENDIF ELSE BEGIN
  214.       slice = Reform((Interpolate(vol, $
  215.          vol_ind[*, 0], vol_ind[*, 1], vol_ind[*, 2], Cubic=Keyword_Set(cubic))), $
  216.          x_size, y_size)
  217.    ENDELSE
  218. ENDELSE
  219.  
  220. RETURN, slice
  221. END
  222.